package com.java.sevice;

import com.java.entity.bank1.Bank1UserAccount;
import com.java.entity.bank2.Bank2UserAccount;
import com.java.repository.bank1.Bank1UserAccountRespository;
import com.java.repository.bank2.Bank2UserAccountRespository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
@Slf4j
public class TransferService {
    @Autowired
    private Bank1UserAccountRespository bank1UserAccountRespository;
    @Autowired
    private Bank2UserAccountRespository bank2UserAccountRespository;


    /**
     * 测试相互转账成功
     * 注意Transactional使用的事务管理器是jta
     */
    @Transactional(rollbackFor = Exception.class)
    public void transferMoneySuccess(Long accountId) throws Exception {
        //计算金额并转账
        Bank1UserAccount bank1UserAccount = this.bank1UserAccountRespository.queryByAccountId(accountId);
        Bank2UserAccount bank2UserAccount = this.bank2UserAccountRespository.queryByAccountId(accountId);
        log.info("初始余额 bank1:{} bank2:{} ", bank1UserAccount.getAmount(), bank2UserAccount.getAmount());
        BigDecimal transferAmount = new BigDecimal("100");
        BigDecimal userBank1Amount = bank1UserAccount.getAmount().subtract(transferAmount);
        BigDecimal userBank2Amount = bank2UserAccount.getAmount().add(transferAmount);
        this.bank1UserAccountRespository.updateAmount(accountId, userBank1Amount);
        this.bank2UserAccountRespository.updateAmount(accountId, userBank2Amount);
        log.info("转账成功 金额:{}", transferAmount);
    }

    /**
     * 测试相互转账发生异常
     */
    @Transactional(rollbackFor = Exception.class)
    public void transferMoneyFail(Long accountId) throws Exception {
        //计算金额并转账
        Bank1UserAccount bank1UserAccount = this.bank1UserAccountRespository.queryByAccountId(accountId);
        Bank2UserAccount bank2UserAccount = this.bank2UserAccountRespository.queryByAccountId(accountId);
        log.info("初始余额 bank1:{} bank2:{} ", bank1UserAccount.getAmount(), bank2UserAccount.getAmount());
        BigDecimal transferAmount = new BigDecimal("100");
        BigDecimal userBank1Amount = bank1UserAccount.getAmount().subtract(transferAmount);
        BigDecimal userBank2Amount = bank2UserAccount.getAmount().add(transferAmount);
        this.bank1UserAccountRespository.updateAmount(accountId, userBank1Amount);
        this.bank2UserAccountRespository.updateAmount(accountId, userBank2Amount);
        log.info("转账成功 金额:{}", transferAmount);
        //模拟异常
        int i = 1 / 0;
    }

    @Transactional(rollbackFor = Exception.class)
    public void initMoney(Long accountId) {
        BigDecimal money = new BigDecimal("10000");
        this.bank1UserAccountRespository.updateAmount(accountId, money);
        this.bank2UserAccountRespository.updateAmount(accountId, money);
        log.info("账户金额初始化完毕");
    }

    public void printMoney(Long accountId) throws Exception {
        Thread.sleep(1000);
        Bank1UserAccount bank1UserAccount = this.bank1UserAccountRespository.queryByAccountId(accountId);
        Bank2UserAccount bank2UserAccount = this.bank2UserAccountRespository.queryByAccountId(accountId);
        log.info("当前余额 bank1:{} bank2:{} ", bank1UserAccount.getAmount(), bank2UserAccount.getAmount());
    }

    /**
     * 转账成功，但是等待10s
     *
     * @param accountId
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void transferMoneySuccessWait(Long accountId) throws Exception {
        //计算金额并转账
        Bank1UserAccount bank1UserAccount = this.bank1UserAccountRespository.queryByAccountId(accountId);
        Bank2UserAccount bank2UserAccount = this.bank2UserAccountRespository.queryByAccountId(accountId);
        log.info("初始余额 bank1:{} bank2:{} ", bank1UserAccount.getAmount(), bank2UserAccount.getAmount());
        BigDecimal transferAmount = new BigDecimal("100");
        BigDecimal userBank1Amount = bank1UserAccount.getAmount().subtract(transferAmount);
        BigDecimal userBank2Amount = bank2UserAccount.getAmount().add(transferAmount);
        this.bank1UserAccountRespository.updateAmount(accountId, userBank1Amount);
        this.bank2UserAccountRespository.updateAmount(accountId, userBank2Amount);
        log.info("转账成功 金额:{}", transferAmount);
    }
}